package com.yuke.cloud.service.omc.controller.frontend;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuke.cloud.common.base.constant.GlobalConstant;
import com.yuke.cloud.common.base.constant.MQConstants;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.core.mq.RabbitMetaMessage;
import com.yuke.cloud.common.core.mq.RabbitSender;
import com.yuke.cloud.common.core.support.BaseController;
import com.yuke.cloud.common.util.PublicUtil;
import com.yuke.cloud.common.util.wrapper.WrapMapper;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.cmc.dto.CmsSecKillSkuDto;
import com.yuke.cloud.service.api.cmc.dto.CmsSysInfoDto;
import com.yuke.cloud.service.api.cmc.service.CmcFeignApi;
import com.yuke.cloud.service.api.omc.dto.OdsOrderApiDto;
import com.yuke.cloud.service.api.omc.exceptions.OmcBizException;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoDto;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoExDto;
import com.yuke.cloud.service.api.pmc.service.PmcFeignApi;
import com.yuke.cloud.service.api.smc.dto.ShopInfoDto;
import com.yuke.cloud.service.api.smc.service.SmcFeignApi;
import com.yuke.cloud.service.api.wmc.dto.StorageSpecInfoDto;
import com.yuke.cloud.service.api.wmc.dto.WareProductDto;
import com.yuke.cloud.service.api.wmc.dto.WarehouseInfoDto;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.omc.dto.*;
import com.yuke.cloud.service.omc.entity.*;
import com.yuke.cloud.service.omc.recommend.recommend;
import com.yuke.cloud.service.omc.service.*;
import com.yuke.cloud.service.omc.utils.DateUtil;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


/**
 * Created by ssx on 2018/09/03.
 */
//@Api(value = "WEB - OdsOrderController", tags = "处理OdsOrder相关请求", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@RestController
@RequestMapping("/ods/order")
@Slf4j
public class OdsOrderController extends BaseController {
    @Resource
    private OdsPointsService odsPointsService;
    @Resource
    private OdsOrderService odsOrderService;
    @Resource
    private OdsOrderGoodsService odsOrderGoodsService;
    @Resource
    private PayController payController;
    @Resource
    private OdsBillService odsBillService;
    @Resource
    private OdsBillPayController odsBillPayController;
    @Resource
    private OdsBillController odsBillController;
    @Resource
    private WmcStorageFeignApi wmcStorageFeignApi;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RabbitSender rabbitSender;
    @Resource
    private CmcFeignApi cmcFeignApi;
    @Resource
    private SmcFeignApi smcFeignApi;
    @Resource
    private OdsPayOrderService odsPayOrderService;
    @Resource
    private PmcFeignApi pmcFeignApi;
    @Resource
    private OdsShopCartService odsShopCartService;
    @Resource
    private WxPayController wxPayController;
    @Resource
    private OdsPointsController odsPointsController;
    @Resource
    private OdsAwardRecordService odsAwardRecordService;

    @GetMapping("/test")
    public void test() throws Exception {
        redisTemplate.opsForValue().set("key1", "value1", 30, TimeUnit.SECONDS);
        Object key1 = redisTemplate.opsForValue().get("key1");
        System.out.println(key1);
    }

    @PostMapping("/updateStatus")
    @ApiOperation(httpMethod = "POST", value = "修改一条记录")
    public Wrapper updateStatus(@ApiParam(name = "odsUserPoint", value = "需要修改的内容") @RequestBody OdsOrder odsOrder) {
        odsOrderService.update(odsOrder);

        //取消订单，如果有发货派送任务，删除发货派送任务
        if (odsOrder.getOrderStatus().equals((byte)3)){
            smcFeignApi.updateSendDeleteTag(odsOrder.getOrderId());
        }
        return WrapMapper.ok();
    }


    @GetMapping("/whetherItCanBeRefund/{orderId}")
    public Wrapper whetherItCanBeRefund(@ApiParam(name = "orderId", value = "记录id") @PathVariable Long orderId) {
        OdsOrder byId = odsOrderService.findById(orderId);
        if (byId == null) {
            return WrapMapper.error("未找到订单！");
        }
        Byte payStatus = byId.getPayStatus();

        // add by wg 20190326 如果用户在还没有发货前进行订单取消，此时不能退款
        Byte status = byId.getOrderStatus();
        if (status.toString().equals("3") || status.toString().equals("6")) {
            //订单已取消3，或者订单作废6
            return WrapMapper.ok(0);
        }

        if (byId.getPayType() != 0 && byId.getPayType() != 8 && payStatus.toString().equals("0")) {  // mod by wg 20190711 增加货到付款处理方式
            return WrapMapper.ok(0);
        } else {
            //货到付款
            Date sendTime = byId.getSendTime();
            if (sendTime == null || PublicUtil.isEmpty(sendTime)) {
                sendTime = byId.getCreateTime();
            }

            Long l =new Date().getTime() - sendTime.getTime();
            Long i = 24 * 60 * 60 * 1000 * 60L;  // todo 为什么是60天？
            Byte orderStatus = byId.getOrderStatus();
            if (l >= i) {
                return WrapMapper.ok(0);
            } else if (orderStatus.toString().equals("4") || orderStatus.toString().equals("5")) {
                //退货4，或部分退货5
                return WrapMapper.ok(0);
            } else {
                System.out.println("这里可以退款++++++++++++++++++++++++++++++++++");
                return WrapMapper.ok(1);
            }

        }

    }

    // todo V1.1版没有店铺线上库存，删除掉，用其他的接口
    //此接口用户向商铺下单
//    @PostMapping
//    @ApiOperation(httpMethod = "POST", value = "新增一条记录")
//    public Wrapper add(@RequestBody JSONObject jsonObject) {
//        System.out.println(jsonObject);
//
//        //获取需要支付价格
//        Object totalpay = jsonObject.get("payinfo");
//        Map s1 = (Map) totalpay;
//        double totalpay1 = Double.parseDouble(s1.get("totalpay").toString());
//        //用户信息
//        Object userinfo = jsonObject.get("userinfo");
//        Map userinfo1 = (Map) userinfo;
//        Object userid = userinfo1.get("userid");
//
//        //收货方信息
//        Object totalpay2 = jsonObject.get("receive");
//        Map receiceinfo = (Map) totalpay2;
//        //商品集合
//        Object products = jsonObject.get("products");
//        List<Map<String, String>> products1 = (List<Map<String, String>>) products;
//        //运费集合
//        Object transprice = jsonObject.get("transprice");
//        List<Map> transprice1 = (List<Map>) transprice;
//        System.err.println(transprice1);
//
//        // add by wg 20190322 增加配送方式
//        String shippingType = "2"; // 运送方式，0：同城即时达（仓库发还是店铺发暂时还不确定），1：物流快递，2：同城快送（一般24小时左右送达），3：即时达（云顶店铺发货），4：即时达（由仓库发货）
//        Object shippingTypeObj = jsonObject.get("shippingtype");
//        if (PublicUtil.isNotEmpty(shippingTypeObj)) {
//            Map shippingTypeMap = (Map) shippingTypeObj;
//            shippingType = shippingTypeMap.get("type").toString();
//        }
//
//        // add by wg 20190329 对提交的订单先判断是否满足库存
//        Map mapResult = odsOrderService.haveShopStockCount(products1);
//        if (mapResult.containsKey("no")) {
//            return WrapMapper.wrap(Wrapper.SUCCESS_CODE, "店铺：" + mapResult.get("no") + " 有商品库存不足，请检查后重新提交订单");
//        }
//
//        // add by wg 20190402 用户留言集合，如果没有用户留言，则为空，不传
//        //商品集合
//        Object postscriptsTemp = jsonObject.get("postscripts");
//        List<Map<String, String>> postscripts = (List<Map<String, String>>) postscriptsTemp;
//
//        // add by wg 20190328 如果订单重新提交，则只更新订单表，不用新生成订单
//        Long orderId = null;
//        Object orderIdTemp = jsonObject.get("orderId");
//        if (PublicUtil.isNotEmpty(orderIdTemp)) {
//            orderId = Long.valueOf(orderIdTemp.toString());
//        }
//
//        //生成订单，生成订单详情表，并且预定货物(让库存减少一件)
//        List<OdsOrderGoods> orderGoods = odsOrderService.Creatord(orderId, products1, Long.valueOf(userid.toString()), receiceinfo, transprice1, shippingType, postscripts);
//        String back = null;
//        if (orderGoods != null && orderGoods.size() > 0) {
//            odsOrderGoodsService.savelist(orderGoods);
//            bookProductAndTimeout(orderGoods, "yes");
//            //backString 方法将订单的id拼接成逗号分隔开的字符串，在支付的时候传入控制器“pay_order_ids”
//            back = backString(orderGoods);
//        } else if (orderId != null){
//            back = orderIdTemp.toString();
////            log.info("+++++++++++back={}", back);
//        }
//
//        if (PublicUtil.isNotEmpty(back)) {
//            System.out.println(back);
//            System.out.println("准备进入支付系统");
//            Map<String, Object> map = new HashMap<String, Object>();
//            map.put("paytype", "normal");
//            map.put("pay_order_ids", back);
//            map.put("totalpay", totalpay1/100);
//            JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
//            Wrapper wrapper = payController.orderPay(jsonObject1);
//            Object result = wrapper.getResult();
//            return WrapMapper.ok(result);
//        } else {
//            return WrapMapper.error("生成订单失败");
//        }
//    }

    /**
     * 预定仓库货物,和订单支付计时(redis过期事件)
     *
     * @param orderGoods
     */
//    public void bookProductAndTimeout(List<OdsOrderGoods> orderGoods, String s) {
////s区分是用户发货，还是店铺发货，店铺发货则店铺货物不用减少
//        List<Map> listz = new ArrayList<Map>();
//        List<Map> listf = new ArrayList<Map>();
//        for (int i = 0; i < orderGoods.size(); i++) {
//            Map mapz = new HashMap();
//            Map mapf = new HashMap();
//            OdsOrderGoods odsOrderGoods = orderGoods.get(i);
//            Long orderId = odsOrderGoods.getOrderId();
//            OdsOrder byId = odsOrderService.findById(orderId);
//            Long shopId = byId.getShopId();
//            Long specId = odsOrderGoods.getSpecId();
//            Integer goodsNum = odsOrderGoods.getGoodsNum();
//            mapz.put("shopId", shopId);
//            mapf.put("shopId", shopId);
//            mapz.put("specId", specId);
//            mapf.put("specId", specId);
//            //预定仓库货品，数量减少
////            System.err.println("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" + goodsNum);
//            mapz.put("goodsNum", goodsNum);
//            mapf.put("goodsNum", -goodsNum);
//
//            mapz.put("isFactory", byId.getIsFactory()); // 用户下单的商品有可能是厂家直销的商品
//            mapz.put("warehouseId", byId.getWarehouseId()); // add by wg 20190727
//            listz.add(mapz);
//            listf.add(mapf);
//        }
//        String s3z = JSON.toJSONString(listz);
//        String s3f = JSON.toJSONString(listf);
////库存减少,店铺对应的库存也要减少,no的时候店铺需要发货，店铺的库存没有变化
//        //todo feign s
//        if (s.equals("yes")) {
//            smcFeignApi.updateStockCount(s3f);  // 店铺商品库存减少
//
//            System.out.println("商店库存减少了吗");
//            wmcStorageFeignApi.preadd(s3z);  // 锁定库存
//            Set set = new HashSet();
//            for (OdsOrderGoods odsOrderGoods : orderGoods) {
//                set.add(odsOrderGoods.getOrderId());
//            }
//            Iterator it = set.iterator();
//            while (it.hasNext()) {
//                String id = "zero:" + it.next().toString();
//                redisTemplate.opsForValue().set(id, "订单", Quartz.second, TimeUnit.SECONDS);
//            }
//
//        } else {
//            wmcStorageFeignApi.preadd(s3z);  // 锁定库存
//            Set set = new HashSet();
//            for (OdsOrderGoods odsOrderGoods : orderGoods) {
//                set.add(odsOrderGoods.getOrderId());
//            }
//            Iterator it = set.iterator();
//            while (it.hasNext()) {
//                String id = "first:" + it.next().toString();
//                //redisTemplate.opsForValue().set(id, "订单", 10, TimeUnit.HOURS);
//                redisTemplate.opsForValue().set(id, "订单", Quartz.second, TimeUnit.SECONDS);
//            }
//        }
//
//    }

//    private String backString(List<OdsOrderGoods> orderGoods) {
//        StringBuilder sb = new StringBuilder();
//        Set set = new HashSet();
//        for (OdsOrderGoods odsOrderGoods : orderGoods) {
//            set.add(odsOrderGoods.getOrderId());
//        }
//        Iterator iterator = set.iterator();
//        while (iterator.hasNext()) {
//            String next = iterator.next().toString();
//            sb.append(next + ",");
//        }
//        String s = sb.toString();
//        String substring = s.substring(0, s.lastIndexOf(","));
//        return substring;
//
//    }


    //商户向平台下单,运费没有单独传递过来保存，运费算到总的付款中

    /**
     * note 此接口不再使用
     * @param jsonObject
     * @return
     */
//    @PostMapping("/shop")
//    @ApiOperation(httpMethod = "POST", value = "新增一条记录")
//    public Wrapper shopOdsAdd(@RequestBody JSONObject jsonObject) {
//        //先判断是发货还是仓库划拨。发货就是普通仓库一样，仓库划拨只需要修改店铺的商品库存就可以，不用发货但是也要生成支付订单。
//        Object ordertype = jsonObject.get("ordertype");
//        Map ordertype2 = (Map) ordertype;
//        String send = ordertype2.get("send").toString();
//        //获取需要支付价格
//        Object totalpay = jsonObject.get("payinfo");
//        Map s1 = (Map) totalpay;
//        Object totalpay9 = s1.get("totalpay");
//        double totalpay1 = Double.parseDouble(totalpay9.toString());
//
//        //用户信息
//        Object userinfo = jsonObject.get("userinfo");
//        Map userinfo1 = (Map) userinfo;
//        //用户id，登陆者id
//        Object userid = userinfo1.get("userid");
//        //登陆者为店铺管理员，所以就有店铺id
//        Object shopid3 = userinfo1.get("shopid");
//        //Long regioncityid = wmcStorageFeignApi.getwarehouseinfo(Long.valueOf(shopid3.toString()));
//
//        //收货方信息
//        Object totalpay2 = jsonObject.get("receive");
//        Map receivemap = null;
//        if (!(totalpay2 == null && totalpay2.toString().equals(""))) {
//            receivemap = (Map) totalpay2;
//        }
//        //商品集合
//        Object products = jsonObject.get("products");
//        List<Map<String, String>> products1 = (List<Map<String, String>>) products;
//
//        // add by wg 20190322 增加配送方式
//        String shippingType = "2"; // 运送方式，0：同城即时达（仓库发还是店铺发暂时还不确定），1：物流快递，2：同城快送（一般24小时左右送达），3：即时达（云顶店铺发货），4：即时达（由仓库发货）
//        Object shippingTypeObj = jsonObject.get("shippingtype");
//        if (PublicUtil.isNotEmpty(shippingTypeObj)) {
//            Map shippingTypeMap = (Map) shippingTypeObj;
//            shippingType = shippingTypeMap.get("type").toString();
//        }
//
//        if (send.equals("no")) {
//            Wrapper getwarehouseidbyshopid = wmcStorageFeignApi.getwarehouseidbyshopid(Long.valueOf(shopid3.toString()));
//            if (getwarehouseidbyshopid == null) {
//                return WrapMapper.ok("服务器故障");
//            }
//            Object result1 = getwarehouseidbyshopid.getResult();
//            if (result1 == null || receivemap.toString().equals("")) {
//                return WrapMapper.ok("服务器故障");
//            }
//            Long warehouseid = Long.valueOf(result1.toString());
//            Long createoderbyshop = odsStockOrderService.createoderbyshop(products1, Long.valueOf(shopid3.toString()), totalpay1, Long.valueOf(shopid3.toString()), warehouseid);
//            Timeout(createoderbyshop);
//            //backString 方法将订单的id拼接成逗号分隔开的字符串，在支付的时候传入控制器“pay_order_ids”
//            //String back = backString(orderdetail);
//            //system.out.println(back);
//            //system.out.println("准备进入支付系统");
//            Map<String, Object> map = new HashMap();
//            //谁支付的，那种用户支付。normal普通用户，shopnotsend店铺不发货。shopsend店铺发货
//            map.put("paytype", "shopnosend");
//            map.put("pay_order_ids", createoderbyshop);
//            map.put("totalpay", totalpay1 / 100);
//            JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
//            Wrapper wrapper = payController.orderPay(jsonObject1);
//            Object result = wrapper.getResult();
//            return WrapMapper.ok(result);
//
//        }
//
//        // add by wg 20190402 增加线下单用户留言信息
//        String postscript = "";
//        if (PublicUtil.isNotEmpty(jsonObject.get("postscripts"))) {
//            postscript = jsonObject.get("postscripts").toString();
//        }

        /**
         * 修改订单状态1用户购买（正常价格） 2店铺周转不发货（价格便宜） 0店铺购买发货(价格便宜)
         * **/

//        //数据从data里面解析,需要商户id
//        List<OdsOrderGoods> orderdetail = odsOrderService.createoderbyshop(products1, Long.valueOf(userid.toString()), totalpay1, Long.valueOf(shopid3.toString()), "0", receivemap, shippingType, postscript);
//        odsOrderGoodsService.savelist(orderdetail);
//        bookProductAndTimeout(orderdetail, "no");
//        //backString 方法将订单的id拼接成逗号分隔开的字符串，在支付的时候传入控制器“pay_order_ids”
//        String back = backString(orderdetail);
//        Map<String, Object> map = new HashMap();
//        map.put("paytype", "shopsend");
//        map.put("pay_order_ids", back);
//        map.put("totalpay", totalpay1 / 100);
//        JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
//        Wrapper wrapper = payController.orderPay(jsonObject1);
//        Object result = wrapper.getResult();
////        System.out.println(receivemap);
//        return WrapMapper.ok(result);
//    }

//    private void Timeout(Long ids) {
//        String id = "second:" + ids;
//        //redisTemplate.opsForValue().set(id, "订单", 10, TimeUnit.HOURS);
//        redisTemplate.opsForValue().set(id, "订单", Quartz.second, TimeUnit.SECONDS);
//    }


    //用户或者商户删除只是修改订单的状态，什么时候真正删除由app后台决定
    @DeleteMapping("/userorshop/{id}")
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除一条记录")
    public Wrapper statesDelete(@PathVariable Long id) {
        OdsOrder odsOrder = odsOrderService.findById(id);
        Byte status = odsOrder.getOrderStatus();
        if (status == (byte) 2 || status == (byte) 3) {
            // mod by wg 20190727
//            odsOrder.setIsCheckout(true);
            odsOrder.setIsDelete(true);
            odsOrderService.update(odsOrder);
            return WrapMapper.ok();
        }
        return WrapMapper.error("订单无法删除");

    }

    //系统物理删除
    @DeleteMapping("/system/{id}")
    @ApiOperation(httpMethod = "DELETE", value = "根据id删除一条记录")
    public Wrapper delete(@ApiParam(name = "id", value = "记录id") @PathVariable Long id) {
        OdsOrder odsOrder = odsOrderService.findById(id);
        OdsOrderGoods odsOrderGoods = new OdsOrderGoods();
        odsOrderGoods.setOrderId(odsOrder.getOrderId());
        List<OdsOrderGoods> odsOrderGoods1 = odsOrderGoodsService.select(odsOrderGoods);
        odsOrderGoodsService.batchDelete(odsOrderGoods1);
        odsOrderService.deleteById(id);
        return WrapMapper.ok();
    }

    /**
     * 用户支付后直接退款，未付款订单取消处理
     * @param odsOrder
     * @return
     */
    @PutMapping
    @ApiOperation(httpMethod = "PUT", value = "修改一条记录")
    public Wrapper update(@ApiParam(name = "odsOrder", value = "需要修改的内容") @RequestBody OdsOrder odsOrder) {
        Long orderId = odsOrder.getOrderId();
        OdsOrderGoods odsOrderGoods = new OdsOrderGoods();
        odsOrderGoods.setOrderId(orderId);

        OdsOrder byId = odsOrderService.findById(orderId);
        List<OdsOrderGoods> select = odsOrderGoodsService.select(odsOrderGoods);
        //List<Map> listz = new ArrayList<>();
        List<Map> listf = new ArrayList<>();


        // add by wg 20190605 判断秒杀商品
        List<CmsSecKillSkuDto> cmsSecKillSkuDtos = odsOrderService.getSecKillSkus();

        Boolean tag = false;
        for (int j = 0, n = select.size(); j < n; j++) {
//            Map mapz = new HashMap<>();
            Map mapf = new HashMap<>();
            OdsOrderGoods odsOrderGoods1 = select.get(j);
//            mapz.put("shopId", byId.getShopId());
            mapf.put("shopId", byId.getShopId());
//            mapz.put("specId", odsOrderGoods1.getSpecId());
            mapf.put("specId", odsOrderGoods1.getSpecId());
            Integer goodsNum = odsOrderGoods1.getGoodsNum();
//            mapz.put("goodsNum", goodsNum);
            mapf.put("goodsNum", -goodsNum);

            mapf.put("isFactory", byId.getIsFactory()); // 用户下单的商品有可能是厂家直销的商品
            mapf.put("warehouseId", byId.getWarehouseId());  // add by wg 20190727
//            listz.add(mapz);
            listf.add(mapf);

            for (CmsSecKillSkuDto cmsSecKillSkuDto : cmsSecKillSkuDtos) {
                if (cmsSecKillSkuDto.getSpecId().longValue() == odsOrderGoods1.getSpecId().longValue()) {
                    cmsSecKillSkuDto.setStoreCount(cmsSecKillSkuDto.getStoreCount());
                    if (cmsSecKillSkuDto.getLockCount() - goodsNum > 0) {
                        cmsSecKillSkuDto.setLockCount(cmsSecKillSkuDto.getLockCount() - goodsNum);
                    } else {
                        cmsSecKillSkuDto.setLockCount(0);
                    }
                    if (cmsSecKillSkuDto.getSaledCount() - goodsNum > 0) {
                        cmsSecKillSkuDto.setSaledCount(cmsSecKillSkuDto.getSaledCount() - goodsNum);
                    } else {
                        cmsSecKillSkuDto.setSaledCount(0);
                    }
                    System.out.println("cmsSecKillSkuDto============" + cmsSecKillSkuDto);
                }
            }

            if (odsOrderGoods1.getGoodsStatus().equals((byte)4)){
                tag = true;
            }
        }

        if (tag){
            //兑换商品，在取消订单时的处理
            odsAwardRecordService.rebackAwardRecord(odsOrder);
        }
        Integer amountPayable = odsOrder.getAmountPayable();
        Byte shippingStatus = byId.getShippingStatus();
        //String sz = JSON.toJSONString(listz);
        String sf = JSON.toJSONString(listf);
        if (odsOrder.getOption().equals("needrefund")) {  // 已成功支付及货到付款的订单走此流程

            int ret = 0;

            // add by wg 20190322 只有已经付款但还未发货是订单可以取消退款
            if (shippingStatus.equals((byte)2)) {
                return WrapMapper.error("商品已发货中，无法退款取消订单");
            }
            //PayType支付平台类型0货到付款  PayStatus支付状态0未付款
            if (byId.getPayType() != 0 && byId.getPayStatus() == 0) {
                return WrapMapper.error("商品还未付款，无法退款取消订单");
            }


            //支付类型为在线支付
            if (byId.getPayType().toString().equals("2") || byId.getPayType().toString().equals("3")
                    || byId.getPayType().toString().equals("6") || byId.getPayType().toString().equals("7") ) {
                Example example = new Example(OdsPayOrder.class);
                Example.Criteria criteria = example.createCriteria();
                criteria.andLike("orderIds", "%" + orderId + "%");
                List<OdsPayOrder> odsPayOrders = odsPayOrderService.selectByExample(example);
                OdsPayOrder odsPayOrder = odsPayOrders.get(0);
                Long out_trade_no = odsPayOrders.get(0).getPayId();
                odsOrder.setPayStatus((byte) 0);
                Map map = new HashMap();
                map.put("orderId", orderId);
                double v = Double.parseDouble(amountPayable.toString());

                if (byId.getPayType().toString().equals("2") ) {  // 支付宝原路退回
                    map.put("refund_amount", v / 100);
                    map.put("out_trade_no", out_trade_no);
                    JSONObject jsonObject = new JSONObject(map);
                    ret = payController.orderPayRefund(jsonObject);
                    //todo 取消订单减积分
                    if (ret > 0){
                        reducePoint(byId,(byte) 8);
                    }
                } else if (byId.getPayType().toString().equals("3")  ) {  // 微信支付原路退回
                    map.put("refund_amount", amountPayable);
                    if (odsPayOrder != null && odsPayOrder.getAmountPaid() != null && odsPayOrder.getAmountPaid() > 0) {
                        map.put("total_fee", odsPayOrder.getAmountPaid());
                    } else {
                        map.put("total_fee", amountPayable);
                    }
                    map.put("out_trade_no", out_trade_no);
                    map.put("out_refund_no", orderId);
                    JSONObject jsonObject = new JSONObject(map);
                    ret = wxPayController.payback(jsonObject);
                    //todo 取消订单减积分
                    if (ret > 0){
                        reducePoint(byId,(byte) 8);
                    }
                }else if (byId.getPayType().toString().equals("6") ) {  // 支付宝原路退回
                    map.put("refund_amount", v / 100);
                    map.put("out_trade_no", out_trade_no);
                    JSONObject jsonObject = new JSONObject(map);
                    ret = payController.orderPayRefund(jsonObject);
                    //todo 取消订单退还加积分
                    if (ret > 0){
                        reducePoint(byId,(byte) 5);
                    }
                } else if (byId.getPayType().toString().equals("7")  ) {  // 微信支付原路退回
                    map.put("refund_amount", amountPayable);
                    if (odsPayOrder != null && odsPayOrder.getAmountPaid() != null && odsPayOrder.getAmountPaid() > 0) {
                        map.put("total_fee", odsPayOrder.getAmountPaid());
                    } else {
                        map.put("total_fee", amountPayable);
                    }
                    map.put("out_trade_no", out_trade_no);
                    map.put("out_refund_no", orderId);
                    JSONObject jsonObject = new JSONObject(map);
                    ret = wxPayController.payback(jsonObject);
                    //todo 取消订单退还加积分
                    if (ret > 0){
                        reducePoint(byId,(byte) 5);
                    }

                }
            }else if (byId.getPayType().toString().equals("4")) {  // 账户余额支付原路退回
                    OdsBill bill = odsBillService.selectLastOneByUserId(byId.getUserId());
                    if (bill != null && bill.getBalance() > 0) {
                        OdsBill odsBill = new OdsBill();
                        odsBill.setBillId(generateId());
                        odsBill.setAmount(byId.getAmountPayable());
                        odsBill.setUserId(byId.getUserId());
                        odsBill.setOrderIds(byId.getOrderId().toString());
                        odsBill.setBillType((byte) 6);//退还
                        odsBill.setBalanceType((byte) 1);//完成
                        odsBill.setBalance(bill.getBalance());
                        if (odsBillPayController.doBillUpdate(odsBill)>0){
                            ret =1;
                            //todo 取消订单退减积分
                            reducePoint(byId,(byte) 8);
                        }

                    }

            } else if (byId.getPayType().toString().equals("5")) {  // 积分支付原路退回
                OdsPoints points = odsPointsService.selectLastOneByUserId(byId.getUserId());
                if (points != null && points.getPointBalance() > 0) {
                    OdsPointsDto odsPoints = new OdsPointsDto();
                    odsPoints.setPointId(generateId());
                    //odsPoints.setNumber(byId.getAmountPayable());
                    odsPoints.setNumber(byId.getDiscount()); //20200221积分支付时，支付积分存入discount
                    odsPoints.setUserId(byId.getUserId());
                    odsPoints.setOrderId(byId.getOrderId().toString());
                    //todo 取消订单退还加积分
                    odsPoints.setPointType((byte) 5);//退还
                    odsPoints.setPointStatus((byte)0);
                    odsPoints.setPointBalance(points.getPointBalance());
                    if(odsPointsService.doPointUpdate(odsPoints) > 0){
                        ret =1;
                    }

                }

            }else if (byId.getPayType() == 0) {

                if (shippingStatus.equals((byte)2)) {
                    return WrapMapper.error("商品已发货中，无法退款取消订单");
                }
                //todo 取消订单退积分
                reducePoint(byId,(byte) 8);
                ret = 1;
            }

            if (ret == 1) {
                odsOrderService.update(odsOrder);
                Byte orderType = byId.getOrderType();
                if (orderType.toString().equals("1")) { // 用户向店铺下单
                    //库存增加，锁定的库存不变
                    // mod by wg 20190322
                    //wmcStorageFeignApi.preadd3(sz);
                    wmcStorageFeignApi.preadd(sf);  // 仓库实际锁定库存还原
//                    smcFeignApi.updateStockCount(sz);  // 店铺商品库存对应增加 V1.1版没有店铺线上库存

                    // add by wg 20190606 增加秒杀活动商品的处理
                    if (cmsSecKillSkuDtos != null && cmsSecKillSkuDtos.size() > 0) {
                        for (CmsSecKillSkuDto cmsSecKillSkuDto : cmsSecKillSkuDtos) {
                            System.out.println("打印订单取消后，库存还原情况");
                            System.out.println("StoreCount=" + cmsSecKillSkuDto.getStoreCount());
                            System.out.println("LockCount=" + cmsSecKillSkuDto.getLockCount());
                            System.out.println("SaledCount=" + cmsSecKillSkuDto.getSaledCount());

                        }
                        cmcFeignApi.updateSecKillSkusCount(cmsSecKillSkuDtos);
                    }

                } else if (orderType.toString().equals("2")) {  // 店铺向平台下线下单
                    // mod by wg 20190322
//                    wmcStorageFeignApi.preadd(sz);
                    wmcStorageFeignApi.preadd(sf); // 仓库实际锁定库存还原
                }
                //优惠券返还
                String id = "CouponReceiveIdAndOrderId:" + odsOrder.getOrderId();
                Map<String, String> map = (Map<String, String>) redisTemplate.opsForValue().get(id);
                System.out.println("优惠券返还" + map);
                if (map != null) {
                    Long couponReceiveId = Long.valueOf(map.get("CouponReceiveId"));
                    cmcFeignApi.updateCouponReceiveBack(couponReceiveId);
                }

                redisTemplate.delete(id);

                return WrapMapper.ok();
            } else {
                return WrapMapper.error("退款/取消订单失败");
            }
        } else {
            if (shippingStatus.equals((byte)2)) {
                return WrapMapper.error("商品已发货中，无法退款取消订单");
            }
            odsOrderService.update(odsOrder);

            if (byId.getPayStatus().intValue() == 0) {
                //未付款，然后又取消，把库存数量加回来，同时删除redis
                if (byId.getOrderType().intValue() == 1) {
                    redisTemplate.delete("zero:" + odsOrder.getOrderId());
                    wmcStorageFeignApi.preadd(sf);
//                    smcFeignApi.updateStockCount(sz);  // 用户订单，V1.1版没有店铺线上库存

                    // add by wg 20190606 增加秒杀活动商品的处理
                    if (cmsSecKillSkuDtos != null && cmsSecKillSkuDtos.size() > 0) {
                        cmcFeignApi.updateSecKillSkusCount(cmsSecKillSkuDtos);
                    }

                } else if (byId.getOrderType().intValue() == 2) {
                    redisTemplate.delete("first:" + odsOrder.getOrderId());
                    wmcStorageFeignApi.preadd(sf);
                }

            }

            //取消订单退优惠券
            String id = "CouponReceiveIdAndOrderId:" + odsOrder.getOrderId();
            Map<String, String> map = (Map<String, String>) redisTemplate.opsForValue().get(id);
            if (map != null) {
                Long couponReceiveId = Long.valueOf(map.get("CouponReceiveId"));
                cmcFeignApi.updateCouponReceiveBack(couponReceiveId);
                redisTemplate.delete(id);
            }

            //todo 取消订单退积分
            reducePoint(byId,(byte) 8);
            return WrapMapper.ok();
        }

    }

    private void reducePoint(OdsOrder odsOrder,Byte pointType) {
        OdsPointsDto odsPointsDto = new OdsPointsDto();

        odsPointsDto.setOrderId(odsOrder.getOrderId().toString());
        odsPointsDto.setUserId(odsOrder.getUserId());
        odsPointsDto.setPointType(pointType);//

        if (odsOrder.getOrderType().toString().equals("2")) {   //店铺下单
            odsPointsDto.setPointAspect((byte) 2); //B端
            odsPointsDto.setNumber(Math.round(odsOrder.getAmountPayable() / GlobalConstant.SHOP_POINT_RATE));
        } else {
            odsPointsDto.setPointAspect((byte) 1);  //C端
            odsPointsDto.setNumber(odsOrder.getAmountPayable());
        }
        //如果是积分混合购退订单，只退支付的积分
        if (odsOrder.getPayType().toString().equals("6") || odsOrder.getPayType().toString().equals("7")){
            odsPointsDto.setNumber(odsOrder.getDiscount());
        }else{
            //金额换算成积分
            Long shopId = odsOrder.getShopId();
            Long groupId = 220839532667469824L;
            Wrapper wrap = wmcStorageFeignApi.getGroupIdByShopId(shopId);
            if (wrap.getCode() == 200 && wrap.getResult() != null ){
                groupId = Long.valueOf(wrap.getResult().toString());
            }

            CmsSysInfoDto cmsSysInfoDto = cmcFeignApi.getSysInfoDtoByType(groupId,GlobalConstant.SysInfo.SYS_INFO_POINT_REBATE);
            String pointRate = cmsSysInfoDto.getInfoValue();
            odsPointsDto.setNumber(Math.round(odsPointsDto.getNumber() * Float.valueOf(pointRate)));
        }

        odsPointsController.addSignIn(odsPointsDto);
    }

    /**
     * 修改指定订单状态，如云顶店铺将即时达订单（未指定谁配送）修改成店铺或云顶店铺，同时更改订单状态为备货
     * 对于发货，如果是云顶店铺直接选择自配送，则订单状态为配送中，由前端做相关逻辑处理；如果是店铺接单后触发发货，则前端调用两个接口：
     * 一个是本接口，修改订单状态为发货，另一个是OdsOrderDeliveryController的物流信息保存接口
     * @param odsOrder
     * @return
     */
    @PostMapping("/xiugai")
    @ApiOperation(httpMethod = "POST", value = "修改一条记录")
    public Wrapper update2(@ApiParam(name = "odsOrder", value = "需要修改的内容") @RequestBody OdsOrder odsOrder) {
        odsOrderService.update(odsOrder);

        // add by wg 20190517
        if ((odsOrder.getShippingType() != null && odsOrder.getShippingType() == 4) && (odsOrder.getOption() != null && "modShipType".equals(odsOrder.getOption()))) {  // 配送类型改成仓库即时达配送
            Map map = new HashMap();
            map.put("MessageType", "findWarehouseAdmin");
            map.put("shopIds", odsOrder.getShopId());
            map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
            RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
            rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
            rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
            rabbitMetaMessage.setPayload(JSON.toJSONString(map));
            try {
                rabbitSender.send(rabbitMetaMessage);
            } catch (Exception e) {
                log.error("rabbitSender.send()调用异常");
            }
        }

        // add by wg 20190517 todo 如果订单由未指定的即时达改成云顶店铺配送，暂时不恢复原有的库存，防止店铺没有库存，再次将订单推给仓库发货
        // 由店铺送完货后完成收货确认操作
        if ((odsOrder.getShippingStatus() != null && odsOrder.getShippingStatus() == 3) && (odsOrder.getShippingType() != null && odsOrder.getShippingType() == 3)) {  // 已收货,且由店铺即时达发货则还原库存
            OdsOrderGoods odsOrderGoods = new OdsOrderGoods();
            odsOrderGoods.setOrderId(odsOrder.getOrderId());
            OdsOrder odsOrderInfo = odsOrderService.findById(odsOrder.getOrderId());
            List<OdsOrderGoods> odsOrderGoodsList = odsOrderGoodsService.select(odsOrderGoods);
            List<Map> listSpecInfo = new ArrayList<>();
            for (int j = 0; j < odsOrderGoodsList.size(); j++) {
                Map mapSpecInfo = new HashMap<>();
                OdsOrderGoods odsOrderGoodsTemp = odsOrderGoodsList.get(j);
                mapSpecInfo.put("shopId", odsOrderInfo.getShopId());
                mapSpecInfo.put("specId", odsOrderGoodsTemp.getSpecId());
                Integer goodsNum = odsOrderGoodsTemp.getGoodsNum();
                mapSpecInfo.put("goodsNum", -goodsNum);

                mapSpecInfo.put("isFactory", odsOrderInfo.getIsFactory()); // 用户下单的商品有可能是厂家直销的商品
                mapSpecInfo.put("warehouseId", odsOrderInfo.getWarehouseId()); // add by wg 20190727
                listSpecInfo.add(mapSpecInfo);
            }
            String strSpecInfos = JSON.toJSONString(listSpecInfo);
            wmcStorageFeignApi.preadd(strSpecInfos);  // 仓库实际锁定库存还原
        }

        return WrapMapper.ok();
    }

    @GetMapping("/{id}")
    @ApiOperation(httpMethod = "GET", value = "根据ID获取具体信息")
    public Wrapper<OdsOrder> detail(@ApiParam(name = "id", value = "记录id") @PathVariable Long id) {
        OdsOrder odsOrder = odsOrderService.findById(id);
        return WrapMapper.ok(odsOrder);
    }

    //用户查询自己的订单
    @PostMapping("/getorder")
    @ApiOperation(httpMethod = "POST", value = "分页获订单状态记录（全部，已付款，未付款，未评价）有记录")
    public Wrapper<PageInfo<OdsOrder>> list(@RequestBody JSONObject jsonObject,
                                            @ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                            @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size) {
        if (jsonObject == null) {
//            return null;
            List<OdsOrder> tempList = new ArrayList<>();
            PageInfo pageInfo = new PageInfo(tempList);
            return WrapMapper.ok(pageInfo);
        }
        if (jsonObject.get("userid") == null || jsonObject.get("userid").toString().equals("") || jsonObject.get("userid").toString().equals("undefined") || jsonObject.get("condition") == null || jsonObject.get("condition").toString().equals("") || jsonObject.get("condition").toString().equals("undefined")) {
//            return null;
            List<OdsOrder> tempList = new ArrayList<>();
            PageInfo pageInfo = new PageInfo(tempList);
            return WrapMapper.ok(pageInfo);
        }
        String id = jsonObject.get("userid").toString();
        String condition = jsonObject.get("condition").toString();

        List<OdsOrder> list = null;
        List<OdsOrder> odsOrders = new ArrayList<>();

        PageInfo pageInfo = new PageInfo(odsOrders);  // add by wg 20190403 增加分页查询

        Byte orderType = 1;  //默认为用户订单
        if (jsonObject.get("orderType") != null && !jsonObject.get("orderType").toString().equals("")) {
            orderType = Byte.valueOf(jsonObject.get("orderType").toString());
        }
        //查询所有
        if (condition.equals("all")) {
            // mod by wg 20190404 根据创建时间倒序排
            Example example = new Example(OdsOrder.class);
            example.setOrderByClause("create_time desc");
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("userId", Long.valueOf(id));
            criteria.andEqualTo("orderType", orderType);

//            OdsOrder ods = new OdsOrder();
//            ods.setUserId(Long.valueOf(id));
//            ods.setOrderType((byte) 1);

            PageHelper.startPage(page, size); // add by wg 20190403 增加分页查询
//            list = odsOrderService.select(ods);
            list = odsOrderService.selectByExample(example);

            pageInfo = new PageInfo(list);
            if (list.size() == 0) {
//                return WrapMapper.ok(odsOrders);
                return WrapMapper.ok(pageInfo);
            }
            list = formatit(list);

            pageInfo.setList(list);
        }
        //已经付款,待收货
        if (condition.equals("paid")) {
            OdsOrder ods = new OdsOrder();
            ods.setShippingStatus((byte) 2);
            ods.setUserId(Long.valueOf(id));
            ods.setOrderType(orderType);
            PageHelper.startPage(page, size); // add by wg 20190403 增加分页查询
            list = odsOrderService.findbystatus(ods);

            pageInfo = new PageInfo(list);
            if (list.size() == 0) {
//                return WrapMapper.ok(odsOrders);
                return WrapMapper.ok(pageInfo);
            }
            list = formatit(list);

            pageInfo.setList(list);
        }
        //待付款
        if (condition.equals("unpaid")) {
            OdsOrder ods = new OdsOrder();
            ods.setOrderStatus((byte) 0);
            ods.setPayStatus((byte) 0);
            ods.setOrderType(orderType);
            ods.setPayType((byte) 0);  // 过滤掉货到付款的情况
            ods.setUserId(Long.valueOf(id));
            PageHelper.startPage(page, size); // add by wg 20190403 增加分页查询
            list = odsOrderService.findbystatus(ods);

            pageInfo = new PageInfo(list);
            if (list == null || list.size() == 0) {
//                List<OdsOrder> list10 = new ArrayList<>();
//                return WrapMapper.ok(list10);
                return WrapMapper.ok(pageInfo);
            }
            //获取订单商品信息，订单仓库信息，商品信息详情，店铺信息
            list = formatit(list);

            pageInfo.setList(list);
        }
        //未收货
        if (condition.equals("unconfirmed")) {
            Example example = new Example(OdsOrder.class);
            Example.Criteria criteria = example.createCriteria();
            criteria.andEqualTo("orderType",orderType);
            criteria.andEqualTo("shippingStatus",2);
            criteria.andEqualTo("userId",Long.valueOf(id));
            criteria.andLessThan("orderStatus",3);
            PageHelper.startPage(page, size); // add by wg 20190403 增加分页查询

            list = odsOrderService.selectByExample(example);
            pageInfo = new PageInfo(list);
            if (list.size() == 0) {
                return WrapMapper.ok(pageInfo);
            }
            //获取订单商品信息，订单仓库信息，商品信息详情，店铺信息
            list = formatit(list);
            pageInfo.setList(list);
        }
        //已完成
        if (condition.equals("confirmedandcancelled")) {
            Example example = new Example(OdsOrder.class);
            example.setOrderByClause("create_time desc");
            Example.Criteria criteria = example.createCriteria();
            List list1 = new ArrayList();
            list1.add(2);
            criteria.andEqualTo("orderType", orderType);
            criteria.andIn("orderStatus", list1);
            criteria.andEqualTo("userId", id);

            PageHelper.startPage(page, size); // add by wg 20190403 增加分页查询
            list = odsOrderService.selectByExample(example);
            pageInfo = new PageInfo(list);

            if (list.size() == 0) {
//                return WrapMapper.ok(odsOrders);
                return WrapMapper.ok(pageInfo);
            }
            //获取订单商品信息，订单仓库信息，商品信息详情，店铺信息
            list = formatit(list);

            pageInfo.setList(list);
        }
        //退款售后
        if (condition.equals("refund")) {
            //退款已经完成
            Map map = new HashMap();
            map.put("userId", id);
            // add by wg 20190403 增加分页查询
            map.put("orderType", orderType);
            map.put("page", page);
            map.put("size", size);
            Wrapper getassreturnWrap = wmcStorageFeignApi.getassreturn2(map);
            if (getassreturnWrap == null) {
                List<OdsOrder> tempList = new ArrayList<>();
                pageInfo = new PageInfo(tempList);
                return WrapMapper.ok(pageInfo);
            }
            pageInfo = (PageInfo) getassreturnWrap.getResult();
            List<Map> list1 = (List<Map>) pageInfo.getList();

            if (list1 == null || list1.size() == 0) {
                List<OdsOrder> tempList = new ArrayList<>();
                pageInfo = new PageInfo(tempList);
                return WrapMapper.ok(pageInfo);
            }
            List<Long> getassreturn = new ArrayList<>();
            for (int i = 0; i < list1.size(); i++) {
                getassreturn.add(Long.valueOf(list1.get(i).get("orderId").toString()));
            }
            Example example1 = new Example(OdsOrder.class);
            example1.setOrderByClause("create_time desc");
            Example.Criteria criteria1 = example1.createCriteria();
            criteria1.andEqualTo("orderType", orderType);
            criteria1.andIn("orderId", getassreturn);
            list = odsOrderService.selectByExample(example1);
            if (list.size() == 0) {
                List<OdsOrder> tempList = new ArrayList<>();
                pageInfo = new PageInfo(tempList);
                return WrapMapper.ok(pageInfo);
            }
            for (int i = 0; i < list1.size(); i++) {
                for (int j = 0; j < list.size(); j++) {
                    if (list1.get(i).get("orderId").toString().equals(list.get(j).getOrderId().toString())) {
                        list.get(j).setReturnStatus(list1.get(i).get("returnStatus").toString());
                        if (list1.get(i).get("returnStatus").toString().equals("3")) {
                            list.get(j).setRefuseReason("质检不通过");
                        } else if (list1.get(i).get("returnStatus").toString().equals("7")) {
                            list.get(j).setRefuseReason("商家拒绝退款");
                        }
                        list.get(j).setRefund(Boolean.parseBoolean(list1.get(i).get("is_refund").toString()));
                    }
                }
            }
            //获取订单商品信息，订单仓库信息，商品信息详情，店铺信息
            list = formatit(list);

            pageInfo.setList(list);
        }
        System.out.println("获取订单商品信息，订单仓库信息，商品信息详情，店铺信息："+pageInfo);
        return WrapMapper.ok(pageInfo);
    }

    //获取订单详情
    private List<OdsOrder> formatit(List<OdsOrder> list) {
        List<Long> list1 = new ArrayList<>();
        List<Long> warehouseIds = new ArrayList<>();
        List<Long> shopIds = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            if (list.get(i).getOrderId() != null && !list.get(i).getOrderId().toString().equals("")) {
                list1.add(list.get(i).getOrderId());
            }

            if (list.get(i).getWarehouseId() != null && !list.get(i).getWarehouseId().toString().equals("")) {
                warehouseIds.add(list.get(i).getWarehouseId());
            }

            if (list.get(i).getShopId() != null && !list.get(i).getShopId().toString().equals("")) {
                shopIds.add(list.get(i).getShopId());
            }
        }

        List<WarehouseInfoDto> warehouseInfoDtos = null;
        if (warehouseIds.size() > 0) {
            Wrapper retWrapper = wmcStorageFeignApi.getWarehouseInfo(warehouseIds);
            if (retWrapper != null && retWrapper.getCode() == 200) {
                warehouseInfoDtos = (List<WarehouseInfoDto>) retWrapper.getResult();
            }
        }

        List<ShopInfoDto> shopInfoDtos = null;
        if (shopIds.size() > 0) {
             shopInfoDtos = smcFeignApi.getShopInfoByShopIds(shopIds);

        }

        Example example = new Example(OdsOrderGoods.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andIn("orderId", list1);
        List<OdsOrderGoods> odsOrderGoods = odsOrderGoodsService.selectByExample(example);


        for (int i = 0; i < list.size(); i++) {
            List<OdsOrderGoods> goodsList = new ArrayList<>();
            if (odsOrderGoods != null && odsOrderGoods.size() >0 ){
                List<Long> specIds = odsOrderGoods.stream().map(OdsOrderGoods::getSpecId).collect(Collectors.toList());
                List<ProdSpecInfoDto> prodSpecInfoDtoList  = pmcFeignApi.getSpecDtosBySpecIds(specIds);

                for (int j = 0; j < odsOrderGoods.size(); j++) {
                    if (prodSpecInfoDtoList != null && prodSpecInfoDtoList.size() > 0){
                        for (ProdSpecInfoDto psd : prodSpecInfoDtoList){
                            if (psd.getSpecId().equals(odsOrderGoods.get(j).getSpecId())){
                                odsOrderGoods.get(j).setSpecName(psd.getSpecName());
                                odsOrderGoods.get(j).setImagesAddress(psd.getBigPic());
                            }

                        }
                    }


                    if (list.get(i).getOrderId().toString().equals(odsOrderGoods.get(j).getOrderId().toString())) {
                        goodsList.add(odsOrderGoods.get(j));
                    }
                }
                list.get(i).setGoodsList(goodsList);
            }


            if (warehouseInfoDtos != null) {
                for (int k = 0; k < warehouseInfoDtos.size(); k++) {
                    if (list.get(i).getWarehouseId() != null &&
                            list.get(i).getWarehouseId().toString().equals(warehouseInfoDtos.get(k).getWarehouseId().toString())) {
                        list.get(i).setWarehouseName(warehouseInfoDtos.get(k).getWarehouseName());
                        list.get(i).setWareCityId(warehouseInfoDtos.get(k).getRegionCityId());
                        break;
                    }
                }
            }

            if (shopInfoDtos != null) {
                for (ShopInfoDto item : shopInfoDtos) {
                    if (list.get(i).getShopId() != null &&
                            list.get(i).getShopId().toString().equals(item.getShopId().toString())) {
                        list.get(i).setShopName(item.getShopName());

                        break;
                    }
                }
            }
        }
        return list;
    }


    @RequestMapping(value = "/countsalesbytime", method = RequestMethod.POST)
    public Wrapper CountSalesByTime(@RequestBody JSONObject jsonObject) {
        String bywhat = jsonObject.get("bywhat").toString();
        String begintime1 = jsonObject.get("begintime").toString();
        String endtime1 = jsonObject.get("endtime").toString();
        String shopid = jsonObject.get("shopid").toString();
        Long longshopid = Long.valueOf(shopid);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date begintime = format.parse(begintime1);
            Date endtinme = format.parse(endtime1);
            switch (bywhat.trim()) {
                case ("quarter"):
                    List<Map<String, Object>> odslist = odsOrderService.countsalesbyquarter(begintime, endtinme, longshopid);
                    return WrapMapper.ok(odslist);
                case ("month"):
                    List<Map<String, Object>> odslist1 = odsOrderService.countsalesbymonth(begintime, endtinme, longshopid);
                    return WrapMapper.ok(odslist1);
                case ("day"):
                    List<Map<String, Object>> odslist2 = odsOrderService.countsalesbyday(begintime, endtinme, longshopid);
                    return WrapMapper.ok(odslist2);

            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return WrapMapper.ok("查询错误");
    }

    @RequestMapping(value = "/recommend", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "商品推荐")
    public Wrapper recommend(@RequestBody JSONObject jsonObject) {
        //1.取出购物车商品specId
        List<Long> orignSpecId = new ArrayList<>();
        Object specIds = jsonObject.get("specids");
        Object userId =  jsonObject.get("userId");
        Byte cartType = jsonObject.get("cartType")!= null?Byte.valueOf(jsonObject.get("cartType").toString()) : (byte)1;
        Long shopId = jsonObject.get("shopId")!= null?Long.parseLong(jsonObject.get("shopId").toString()) : 220854931912392704L;
        if (specIds != null){
           orignSpecId = Arrays.stream(specIds.toString().split(",")).map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        }
        //2.购物车为空，取出本人足迹前10条记录的specId，
        else  if (userId != null){
            //取用户浏览商品id
            String key = "User:" + userId + ":Recording";
            Set<Long> specIdset = redisTemplate.opsForZSet().range(key, 0, 9);
            orignSpecId = new ArrayList<>(specIdset);
        }
        //如果还为空，取购物车最新10条
        if (orignSpecId == null || orignSpecId.size() < 1){
            Example example = new Example(OdsShopCart.class);
            Example.Criteria criteria = example.createCriteria();
            example.setOrderByClause("create_time desc");
            //criteria.andEqualTo("userId", id);
            criteria.andEqualTo("cartType", cartType);
            criteria.andCondition("limit"," 0,9");
            List<OdsShopCart> list = odsShopCartService.selectByExample(example);
            orignSpecId = list.stream().map(OdsShopCart::getSpecId).collect(Collectors.toList());
        }
        //3.由specId 获得有这些specId的orderId
        List<Map> orderIds = odsOrderService.recommond01(orignSpecId);

        if (orderIds.size() == 0) {
            return WrapMapper.ok("");
        }
        List<Long> orderIdList = new ArrayList<>();
        for(Map map : orderIds){
            orderIdList.add(Long.valueOf(map.get("order_id").toString()));
        }
       //4.由orderId取出关联的specId，按销量排序，取出前20条
        List<Map> speclist = odsOrderService.recommond02(orderIdList);
        List<Long> listSpecId = new ArrayList<>();
        System.out.println("speclist="+speclist);
        for (Map map : speclist) {
            Long specId = Long.valueOf(map.get("spec_id").toString());
            if (!listSpecId.contains(specId)) {
                listSpecId.add(specId);

            }
        }
        System.out.println("listSpecId="+listSpecId);
        //5.由specId取出商品信息，需要图片，分B端，C端
        List<ProdSpecInfoExDto> prodSpecInfoExDtoList =  wmcStorageFeignApi.getStorageSpecBySpecIds(shopId,listSpecId,cartType);
        System.out.println("prodSpecInfoExDtoList="+prodSpecInfoExDtoList);

        return WrapMapper.ok(prodSpecInfoExDtoList);
    }

    //推荐算法：余弦算法，废弃：冷启动时没有数据返回
    @RequestMapping(value = "/XXXXrecommond/XXXXXXXXXXXXXX", method = RequestMethod.POST)
    @ApiOperation(httpMethod = "POST", value = "商品推荐")
    public Wrapper recommond(@RequestBody JSONObject jsonObject) {
        Object specids = jsonObject.get("specids");
        String[] split = specids.toString().split(",");
        List<Long> orign = new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            orign.add(Long.getLong(split[i]));
        }
        //由specId 取 orderId  10条
        List<Map> list1 = odsOrderService.recommond01(orign);
        if (list1.size() == 0) {
            return WrapMapper.ok("");
        }
        System.out.println(" orderId="+list1);
        //由orderId 取 specId
        List<Long> orderIdList = new ArrayList<>();
        for(Map map : list1){
            orderIdList.add(Long.valueOf(map.get("order_id").toString()));
        }
        List<Map> list2 = odsOrderService.recommond02(orderIdList);
        System.out.println("specId="+list2);
        List<String> list = new ArrayList<>();


        StringBuilder sb = new StringBuilder();
        List<Long> listSpecId = new ArrayList<>();
        for (int j = 0; j < list2.size(); j++) {
            Long specId = Long.valueOf(list2.get(j).get("spec_id").toString());
            if (!listSpecId.contains(specId)) {
                listSpecId.add(specId);
                sb.append(specId.toString()).append(",");
            }
        }
        list.add(sb.toString());
        System.out.println("list"+list);
        String[] shu = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            String s = list.get(i);
            boolean b = s.endsWith(",");
            if (b) {
                String substring = s.substring(0, s.lastIndexOf(","));
                if (substring.contains(",")) {
                    substring.replace(",", " ");
                }
                shu[i] = substring;
            }
            shu[i] = s;
        }

        /**
         * 获取到数据源s
         * **/
        String replace = specids.toString().replace(",", " ");
        String shu1[] = new String[shu.length];
        for (int i = 0; i < shu.length; i++) {
            String s = shu[i];
            String replace1 = s.substring(0, s.lastIndexOf(",")).replace(",", " ");
            System.out.println("replace1="+replace1);
            shu1[i] = replace1;
        }
        System.out.println("shu1[i]="+shu1);
        recommend rec = new recommend();
        rec.fit(shu1);
        double[] doubles = rec.recommendFun(replace);
        System.out.println("doubles="+doubles);
        TreeSet<String> product = rec.getProduct();
        List<String> list3 = new ArrayList<>();
        Iterator<String> iterator = product.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            list3.add(next);
        }
        //firstbig,secondbig
        List<String> what = new ArrayList<>();
        for (int i = 0; i <= doubles.length - 1; i++) {
            what.add((doubles[i] + ":" + list3.get(i)));
        }
        for (int i = 0; i < doubles.length - 1; i++) {
            for (int j = 0; j < doubles.length - 1 - i; j++) {
                if (doubles[j] < doubles[j + 1]) {
                    double aDouble = doubles[j];
                    doubles[j] = doubles[j + 1];
                    doubles[j + 1] = aDouble;
                }
            }
        }
        List<Double> listfinal = new ArrayList<>();
        for (int i = 0; i < doubles.length; i++) {
            if (doubles[i] != 0.0) {
                listfinal.add(doubles[i]);
            }
        }
        System.out.println("listfinal="+listfinal);
        //冒泡排序，相关度大的在前面
        int length = listfinal.size();
        //获取的相似度值
        List<Double> fk = new ArrayList<>();
        if (length >= 6) {
            //获取前六个
            for (int i = 0; i < 6; i++) {
                fk.add(listfinal.get(i));
            }
        } else {
            //有多少获取多少
            for (int i = 0; i < listfinal.size(); i++) {
                fk.add(listfinal.get(i));
            }
        }
        List<String> list4 = new ArrayList<>();
        for (int i = 0; i < fk.size(); i++) {
            for (int j = 0; j < what.size(); j++) {
                if ((fk.get(i) + "").equals(what.get(j).split(":")[0])) {
                    if (!list4.contains(what.get(j).split(":")[1])) {
                        list4.add(what.get(j).split(":")[1]);
                    }
                }
            }
        }
        System.out.println("输出："+list4);
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < list4.size(); i++) {

            if (i != (list4.size() - 1)) {
                stringBuilder.append(list4.get(i)).append(",");
            } else {
                stringBuilder.append(list4.get(i));
            }
        }
        return WrapMapper.ok(stringBuilder.toString());

    }

    //用户确认收货接口
    @GetMapping("/takeover/{id}")
    public Wrapper takeover(@PathVariable Long id) {
        OdsOrder odsOrder = new OdsOrder();
        odsOrder.setOrderId(id);
        odsOrder.setOrderStatus((byte) 2);
        odsOrder.setShippingStatus((byte) 3);
        odsOrderService.update(odsOrder);
        return WrapMapper.ok("success");
    }


    // 获取线下店铺进货返利总额及当月预计返利额
    @GetMapping("/getShopRebate/{id}")
    @ApiOperation(httpMethod = "GET", value = "获取线下店铺进货返利总额及当月预计返利额")
    public Wrapper getShopRebate(@PathVariable Long id) {
        JSONObject amountCheckoutJson = new JSONObject();

        Date begintime1 = DateUtil.monthTimeBegin();
        Date endtime1 = DateUtil.monthTimeEnd();

        //zyq 当月实际返利总额
        //Integer alrdyAmountCheckout = odsOrderService.getAlrdyAmountDiscount(begintime1, endtime1, id);
        Integer alrdyAmountCheckout = 0;
        // todo 目前店铺订货直接在订单中进行优惠，因此，无预估返利 20190727
        Integer preAmountCheckout = 0; // odsOrderService.getPreAmountCheckout(id);
        //zyq 当月满额返利总额
        Integer doAmountCheckout = odsOrderService.getDoAmountCheckout(begintime1, endtime1, id);
        //zyq 当月购买金额
        Integer doAmountMoney = odsOrderService.getDoAmountMoney(begintime1, endtime1, id);
        //累计返利总额
        amountCheckoutJson.put("alrdyAmountCheckout", alrdyAmountCheckout);
        //当月预估返利总额
        amountCheckoutJson.put("preAmountCheckout", preAmountCheckout);
        //当月满额返利总额
        amountCheckoutJson.put("doAmountCheckout", doAmountCheckout);
        //当月购买金额
        amountCheckoutJson.put("doAmountMoney", doAmountMoney);

        return WrapMapper.ok(amountCheckoutJson);
    }

    //此接口用户向商铺下单,用户向平台下单，商户向平台下单
    /**
     * 对于已经有的订单不能更新任何信息，直接进行付款，否则处理很麻烦，如变更地址，会进行原来的商品取消锁定，
     * 新的地址附近是否有足够的库存等一系列复杂操作
     * @param orderInfoDto
     * @return
     */
    @Synchronized
    @PostMapping
    @ApiOperation(httpMethod = "POST", value = "新增订单")
    public Wrapper addOrder(@RequestBody OrderInfoDto orderInfoDto) {
        System.out.println("提交订单参数："+orderInfoDto);

        // 先判断提交的数据是否为空
        if (orderInfoDto == null || orderInfoDto.getUserId() == null || orderInfoDto.getOrderBasicDtos() == null ||
                orderInfoDto.getOrderBasicDtos().size() <= 0 || orderInfoDto.getRecipientDto() == null) {
            return WrapMapper.error("订单数据无效");
        }
        //获取shopId
        Long shopId = orderInfoDto.getOrderBasicDtos().get(0).getShopId();
        //若shopId为空则返回无店铺信息
        if (shopId == null) {
            return WrapMapper.error("订单数据无效，没有店铺信息");
        }

        //阻止反复提交，短时间内重复提交
        Object uId = redisTemplate.opsForValue().get("SendOrderAndUserId:" +orderInfoDto.getUserId());
        if (uId != null){
            return WrapMapper.error("提交太频繁，不可重复提交！");
        }else{
            String id = "SendOrderAndUserId:" +orderInfoDto.getUserId();
            Map<String, String> map = new HashMap();
            map.put("userId", orderInfoDto.getUserId().toString());
            redisTemplate.opsForValue().set(id, map, 10, TimeUnit.SECONDS);
        }



        //定义一个 仓库Id
        Long localWarehouseId = null;
        //根据店铺id查找关联仓库 传入ShopId为空,默认值返回值为6武汉白沙洲仓
        Wrapper wrapperRet = wmcStorageFeignApi.getwarehouseidbyshopid(shopId);
        if (wrapperRet != null && wrapperRet.getCode() == 200 && wrapperRet.getResult() != null) {
            //将店铺所属仓库Id 赋值给localWarehouseId
            localWarehouseId = Long.valueOf(wrapperRet.getResult().toString());
        } else {
            //若返回为空而且不为200状态码而且结果集为空 则抛出异常 微服务不在线,或者网络超时
            throw new OmcBizException(ErrorCodeEnum.GL99990002);
        }

        // 判断订单中的商品库存是否满足订单需求
        List<Long> specIds = new ArrayList<>();  // 本地及厂家直销仓库下的商品ID集合
        Map<Long, Integer> goodsNumMap = new HashMap<>();
        Boolean isUserOrder = true;  // 店铺和用户单不可能一起提交，因此此处在for循环内赋值

        Map<Long, List> wareSpecMap = new HashMap<>();  // 仓库对应的商品

        Map<Long, Integer> stockCountMap = new HashMap<>();

        Map<String, String> mapResult = new HashMap<>();

        if (orderInfoDto.getOrderBasicDtos().get(0).getOrderId() == null){
            Long amountPay=0L;

            //获取订单基本信息集合 循环
            for (OrderBasicDto orderBasicDto : orderInfoDto.getOrderBasicDtos()) {
                //若订单类型 为店铺向平台仓库下单
                if (orderBasicDto.getOrderType() == 2) {
                    isUserOrder = false;
                }
                amountPay += orderBasicDto.getAmountPayable();

                //获取SpecId集合
                List<Long> specIdList = orderBasicDto.getOrderGoodsDtos().stream().map(OrderGoodsDto::getSpecId).collect(Collectors.toList());
                //获取商品所属仓库Id
                Long warehouseId = orderBasicDto.getWarehouseId();
                //根据specId集合 和仓库Id 获取远程仓库可卖商品数量及仓库信息
                Wrapper warehouseWrapper = wmcStorageFeignApi.getRemoteStock(specIdList, warehouseId);

                if (warehouseWrapper != null && warehouseWrapper.getCode() == 200) {
                    List<WareProductDto> list = (List<WareProductDto>) warehouseWrapper.getResult();

                    if (list != null && list.size() > 0) {
                        //获取第一个商品所属仓库Id   未做一个订单中有多个仓库商品的 处理
                        warehouseId = Long.valueOf(list.get(0).getWarehouseId().toString());
                    }
                }
                //todo 判断商品是否被禁用
                Map<Long,Integer> goodsStockMap = new HashMap<>();
                Map<Long,String>  goodsNameMap = new HashMap<>();
                List<StorageSpecInfoDto> storageSpecInfoDtoList = wmcStorageFeignApi.getAllStorageBySpecIds(specIdList, orderBasicDto.getWarehouseId());
                if (storageSpecInfoDtoList != null && storageSpecInfoDtoList.size() > 0){
                    for (StorageSpecInfoDto item : storageSpecInfoDtoList){
                        if (item.getMarketPrice().equals(0) && isUserOrder){
                            return WrapMapper.error("订单商品"+item.getSpecName()+"，市场价格错误！");
                        }
                        if (item.getStockPrice().equals(0) && !isUserOrder){
                            return WrapMapper.error("订单商品"+item.getSpecName()+"，批发价格错误！");
                        }
                        if (item.getNumber() - item.getLockNumber() < 1 ){
                            return WrapMapper.error("订单商品"+item.getSpecName()+"，库存不足！");
                        }
                        //忽略线下手工单
                        if(!item.getIsEnable() && !orderBasicDto.getOrderType().toString().equals("7")){
                            return WrapMapper.error("订单商品"+item.getSpecName()+"，已经下架！");
                        }
                        goodsStockMap.put(item.getSpecId(),item.getNumber() - item.getLockNumber());
                        goodsNameMap.put(item.getSpecId(),item.getSpecName());

                        //todo end
                        Boolean isLocal= true;
                        //若商品所在仓库Id等于0 或则等于店铺所在仓库或为厂家直销订单
                        if (warehouseId == 0L || item.getWarehouseId().equals(localWarehouseId)) {
                            isLocal = true;
                        } else {
                            isLocal = false;
                        }
                        //若isLocalSpec为true
                        if (isLocal) {
                            //若本地及厂家直销仓库下的商品ID集合 不包含传过来的商品Id
                            if (!specIds.contains(item.getSpecId())) {
                                //则将商品id放入集合中
                                specIds.add(item.getSpecId());
                            }
                        } else {
                            //若isLocalSpec为false  根据仓库Id 键 获取仓库对应的商品集合
                            List<Long> remoteSpecs = wareSpecMap.get(item.getWarehouseId());
                            //若商品集合为空
                            if (remoteSpecs == null) {
                                remoteSpecs = new ArrayList<>();
                                //将商品id放入remoteSpecs集合中
                                remoteSpecs.add(item.getSpecId());
                                //再将仓库Id作为键 商品id集合作为值放入map集合中
                                wareSpecMap.put(warehouseId, remoteSpecs);
                                //若remoteSpecs集合不包含该商品Id
                            } else if (!remoteSpecs.contains(item.getSpecId())) {
                                //则将商品Id放入集合中
                                remoteSpecs.add(item.getSpecId());
                            }
                        }
                    }
                }
                //todo end
                Boolean isLocalSpec = true;
                //若商品所在仓库Id等于0 或则等于店铺所在仓库或为厂家直销订单
                if (warehouseId == 0L || warehouseId.equals(localWarehouseId)
                        || (orderBasicDto.getIsFactory() != null && orderBasicDto.getIsFactory())) {
                    isLocalSpec = true;
                } else {
                    isLocalSpec = false;
                }
                //获取商品规格信息集合遍历
                for (OrderGoodsDto orderGoodsDto : orderBasicDto.getOrderGoodsDtos()) {
                    Integer stockNumber = goodsStockMap.get(orderGoodsDto.getSpecId());
                    if (isLocalSpec && stockNumber != null){
                        if (stockNumber < orderGoodsDto.getGoodsNum()){
                            orderGoodsDto.setSpecName(goodsNameMap.get(orderGoodsDto.getSpecId()));
                            return WrapMapper.error("订单商品"+orderGoodsDto.getSpecName()+"，库存不足！");
                        }
                    }

                    //根据商品Id获取商品库存数量
                    Integer num = goodsNumMap.get(orderGoodsDto.getSpecId());
                    //若商品数量为空或小于零
                    if (num == null || num < 0) {
                        //则商品数量为零
                        num = 0;
                    }
                    //将商品Id作为键  库存为值 放入map集合
                    goodsNumMap.put(orderGoodsDto.getSpecId(), orderGoodsDto.getGoodsNum() + num);
               }//for


                //赠品处理
                List<OrderGoodsDto> giftGoodsDtos = odsOrderService.getWmsGiftList(orderBasicDto.getOrderGoodsDtos(),shopId,orderBasicDto.getOrderType());
                if (giftGoodsDtos != null && giftGoodsDtos.size() > 0){
                    orderBasicDto.getOrderGoodsDtos().addAll(giftGoodsDtos);
                }


            }//for


            //若订单金额小于258，返回提示：您的订单金额低于258元，由于近期业务量激增，订单量低于258元的已不再发货，请修改订单。
            //年底改为198元
            Integer  qsl = 19800;
            CmsSysInfoDto cmsSysInfo = cmcFeignApi.getSysInfoDtoByType(220839532667469824L,23);
            System.out.println(cmsSysInfo);
            if (cmsSysInfo != null && cmsSysInfo.getInfoValue() !=null ){
                qsl = Integer.parseInt(cmsSysInfo.getInfoValue());
            }
            if (amountPay > 0 && amountPay < qsl){
                if (orderInfoDto.getOrderBasicDtos().get(0).getOrderType().toString().equals("2")
                        && !orderInfoDto.getOrderBasicDtos().get(0).getPayType().toString().equals("8")
                        && !orderInfoDto.getOrderBasicDtos().get(0).getPayType().toString().equals("9") ){
                    //从数据库提取该用户的订单，如果还未发货，未取消，可以提交新订单
                    Example example = new Example(OdsOrder.class);
                    Example.Criteria criteria = example.createCriteria();
                    criteria.andEqualTo("userId", orderInfoDto.getUserId());
                    criteria.andEqualTo("orderType", (byte)2);
                    criteria.andLessThan("orderStatus",(byte)2);
                    criteria.andLessThan("shippingStatus",(byte)2);
                    Calendar c = Calendar.getInstance();
                    c.setTime(new Date());
                    c.add(Calendar.DATE,-1);
                    criteria.andBetween("createTime",c.getTime(),new Date());
                    if (odsOrderService.selectCountByExample(example)<1){
                        return WrapMapper.error("即日起订单金额低于"+ qsl/100 +"元将不再配送，请您修改订单。");
                    }

                }

            }



            //根据收件人的城市Id 和商品Id集合获取同一个城市仓库中指定商品的库存量
            Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityStockCount(orderInfoDto.getRecipientDto().getRegionCityId(), specIds);
            if (stockCount != null && stockCount.getCode() == 200) {
                Map<Long, Integer> stockCountMapLocal = stockCount.getResult();
                if (stockCountMapLocal != null) {
                    //将商品Id 和对应库存放入集合中
                    stockCountMap.putAll(stockCountMapLocal);
                }
            } else {
                //若拿到的stockCountMapLocal为空则返回 微服务故障，或不在线
                return WrapMapper.error("微服务故障，或不在线");
            }//if
            //遍历wareSpecMap集合  非本地商品
            Iterator itWareSpec = wareSpecMap.keySet().iterator();
            //若存在下一个数据
            while (itWareSpec.hasNext()) {
                //获取仓库Id
                Long warehouseId = Long.valueOf(itWareSpec.next().toString());
                //根据仓库Id获取商品Id集合
                List<Long> wareSpecs = wareSpecMap.get(warehouseId);
                //根据商品对应仓库id 和商品Id集合 获取指定仓库中指定商品的库存量
                Wrapper<Map<Long, Integer>> wrapperStockCount = wmcStorageFeignApi.getWarehouseStockCount(warehouseId, wareSpecs);

                if (wrapperStockCount != null && wrapperStockCount.getCode() == 200) {
                    Map<Long, Integer> stockCountMapRemote = wrapperStockCount.getResult();
                    if (stockCountMapRemote != null) {
                        stockCountMap.putAll(stockCountMapRemote);
                    }
                } else {
                    return WrapMapper.error("微服务故障，或不在线");
                }
            }//while

            // add by wg 20190605 判断秒杀商品，只对用户端
            List<CmsSecKillSkuDto> cmsSecKillSkuDtos = null;
            //个人端购买
            if (isUserOrder) {
                cmsSecKillSkuDtos = odsOrderService.getSecKillSkus();

            }

            Iterator it = goodsNumMap.keySet().iterator();
            while (it.hasNext()) {
                //获取商品specId 转为String
                String key = it.next().toString();
                Integer stockCnt = stockCountMap.get(Long.valueOf(key));
                Integer goodsNum = goodsNumMap.get(Long.valueOf(key));
                //库存数量为空 所选商品数量小于库存数量
                if (stockCnt == null || stockCnt < goodsNum) {

                    return WrapMapper.error("部分商品库存不足或收货地附近可能没有店铺，请检查后重新提交订单");
                }

                // add by wg 20190605 判断秒杀商品
                // todo 从redis中获取活动商品并判断用户是否已经超买,暂时不做购买限制
                if (isUserOrder) {
                    for (CmsSecKillSkuDto cmsSecKillSkuDto : cmsSecKillSkuDtos) {

                        if (cmsSecKillSkuDto.getSpecId().toString().equals(key)) {

                            if ((cmsSecKillSkuDto.getStoreCount() - cmsSecKillSkuDto.getLockCount()) < goodsNum) {

                                return WrapMapper.error("秒杀商品库存不足或收货地附近可能没有店铺，请检查后重新提交订单");
                            }

                            cmsSecKillSkuDto.setStoreCount(cmsSecKillSkuDto.getStoreCount());
                            cmsSecKillSkuDto.setLockCount(cmsSecKillSkuDto.getLockCount() + goodsNum);
                            cmsSecKillSkuDto.setSaledCount(cmsSecKillSkuDto.getSaledCount() + goodsNum);

                        }
                    }
                }
            }
            // todo 保存订单
           mapResult = odsOrderService.saveOrder(orderInfoDto, cmsSecKillSkuDtos, isUserOrder);
        } else {
           mapResult = odsOrderService.saveOrder(orderInfoDto, null, isUserOrder);
        }

        // 生成订单，返回订单ID集合及应支付的总金额



        Byte payType = 2;
        // Byte orderType = 2;
        if (orderInfoDto.getOrderBasicDtos() != null && orderInfoDto.getOrderBasicDtos().size() > 0) {
            payType = orderInfoDto.getOrderBasicDtos().get(0).getPayType();
            //   orderType = orderInfoDto.getOrderBasicDtos().get(0).getOrderType();
        }

        //如果此单使用了红包，标记红包状态
        Long redReceiveId = orderInfoDto.getRedReceiveId();
        if (redReceiveId != null && orderInfoDto.getRedMoney() > 0){
            cmcFeignApi.updateRedReceiveUsered(redReceiveId,mapResult.get("pay_order_ids"));
        }

        //如果此单使用了优惠券，标记使用状态,由于有的版本没传Coupon_receive_id，必须从redis中取值
        Long crId = orderInfoDto.getCouponReceiveId();
        System.out.println("如果此单使用了优惠券，标记使用状态" + crId);
        if (crId != null && crId > 0) {
             //货到付款时，改变优惠券状态，线上支付时由支付回调改变
            if (payType.toString().equals("0") ){
                cmcFeignApi.updateCouponReceive(crId, Long.valueOf(mapResult.get("pay_order_ids").toString()));
            }

        }
        if (payType.toString().equals("0") || payType.toString().equals("8") || payType.toString().equals("9")) {
            // 货到付款方式，线下手工单,免费送
            // add by wg 20190711 增加货到付款方式

            String shopIds = null;
            String warehouseIds = null;
            for (OrderBasicDto orderBasicDto : orderInfoDto.getOrderBasicDtos()) {
                if (orderBasicDto.getShippingType() == 2) {  // 同城快送
                    Long shopIdTemp = orderBasicDto.getShopId();
                    if (shopIdTemp != null) {
                        if (PublicUtil.isEmpty(shopIds)) {
                            shopIds = orderBasicDto.getShopId().toString();
                        } else {
                            shopIds += ",";
                            shopIds += orderBasicDto.getShopId().toString();
                        }
                    }
                }

                Long warehouseId = orderBasicDto.getWarehouseId();
                if (warehouseId != null) {
                    if (PublicUtil.isEmpty(warehouseIds)) {
                        warehouseIds = orderBasicDto.getWarehouseId().toString();
                    } else {
                        warehouseIds += ",";
                        warehouseIds += orderBasicDto.getWarehouseId().toString();
                    }
                }
            }
            //双十一活动，发放优惠券
            addCoupon(mapResult,shopId);
            // todo 此时直接通知仓库准备发货，可将支付成功后的相关业务拿来使用
            Map map = new HashMap();
            map.put("MessageType", "findWarehouseAdmin");
            map.put("warehouseIds", warehouseIds);
            map.put("shopIds", shopIds);
            map.put("body", "你有新的订单需要发货");//"查找仓库管理员");
            RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
            rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
            rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_WMC);
            rabbitMetaMessage.setPayload(JSON.toJSONString(map));
            try {
                rabbitSender.send(rabbitMetaMessage);
            } catch (Exception e) {
                log.error("rabbitSender.send()调用异常");
            }

        } else {  // 线上支付方式
            if (PublicUtil.isNotEmpty(mapResult.get("pay_order_ids")) && PublicUtil.isNotEmpty(mapResult.get("totalpay"))) {
                String orderIds = mapResult.get("pay_order_ids");
//            Integer totalPay = Integer.valueOf(mapResult.get("totalpay"));
                double totalPay = Double.parseDouble(mapResult.get("totalpay"));

                Object result = null;
                log.info("准备进入支付系统，orderIds={}, totalPay={}", orderIds, totalPay);
                Map<String, Object> map = new HashMap<String, Object>();

                map.put("paytype", "normal");
                map.put("pay_order_ids", orderIds);

                if (payType.toString().equals("2")) {  // 支付宝
                    map.put("totalpay", totalPay / 100);

                    JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
                    // todo 调用支付接口
                    log.info("调用支付接口传入参数" + jsonObject1);
                    Wrapper wrapper = payController.orderPay(jsonObject1);
                    log.info("调用支付接口返回参数" + wrapper);

                    result = wrapper.getResult();
                } else if (payType.toString().equals("3")) {  // 微信支付
                    map.put("totalpay", Integer.valueOf(mapResult.get("totalpay")));

                    JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
                    try {
                        System.out.println(jsonObject1);
                        Wrapper wrapper = wxPayController.add(jsonObject1);

                        result = wrapper.getResult();
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        return WrapMapper.error("微信支付失败");
                    }
                } else if (payType.toString().equals("4")) {  // 账户余额支付
                    map.put("totalpay", Integer.valueOf(mapResult.get("totalpay")));
                    map.put("userId", orderInfoDto.getUserId());
                    JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
                    try {
                        Wrapper wrapper = odsBillController.consumer(jsonObject1);

                        result = wrapper.getResult();
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        return WrapMapper.error("账户支付失败");
                    }
                } else if (payType.toString().equals("5")) {//积分支付
                    try {
                        Wrapper wrapper = odsOrderService.reduceOrderPoint(orderInfoDto,orderIds);
                        System.out.println(wrapper);
                        result =WrapMapper.ok(wrapper.getResult());
                        //result = wrapper;
                        System.out.println(result);
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        return WrapMapper.error("积分支付失败");
                    }

                } else if (payType.toString().equals("6")) {//积分混购积分加支付宝
                    JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
                    log.info("调用支付接口传入参数" + jsonObject1);
                    Wrapper wrapper = payController.orderPay(jsonObject1);
                    map.put("totalpay", totalPay / 100);
                    if (wrapper.getCode() > 200){
                        return WrapMapper.error("订单数据无效，支付宝支付错误");
                    }
                    Wrapper wrap = odsOrderService.reduceOrderPoint(orderInfoDto,orderIds);
                    if (wrap.getCode() > 200){
                        return WrapMapper.error("订单数据无效，积分扣减错误");
                    }
                    result = wrapper.getResult();

                } else if (payType.toString().equals("7")) {//积分混合购积分加微信
                    map.put("totalpay", Integer.valueOf(mapResult.get("totalpay")));

                    JSONObject jsonObject1 = JSONObject.parseObject(JSON.toJSONString(map));
                    try {
                        Wrapper wrapper = wxPayController.add(jsonObject1);
                        if (wrapper.getCode() > 200){
                            return WrapMapper.error("订单数据无效，微信支付错误");
                        }
                        Wrapper wra = odsOrderService.reduceOrderPoint(orderInfoDto,orderIds);
                        if (wra.getCode() > 200){
                            return WrapMapper.error("订单数据无效");
                        }
                        result = wrapper.getResult();
                    } catch (Exception e) {
                        log.error(e.getMessage());
                        return WrapMapper.error("微信支付失败");
                    }



                }


                if (result == null) {
                    return WrapMapper.error("支付失败");
                } else {//首单优惠券
                    //根据商户id，到ods_pay_order表查找
                    Example example = new Example(OdsOrder.class);
                    Example.Criteria criteria = example.createCriteria();
                    criteria.andEqualTo("orderStatus", 1);
                    criteria.andEqualTo("shopId", shopId);
                    List<OdsOrder> odsOrders = odsOrderService.selectByExample(example);
                    System.out.println("是否执行优惠券2#发放" + odsOrders);
                    //有记录>1跳过
                    if (odsOrders.size() == 1) {
                        //执行优惠券发放
                        System.out.println("执行优惠券2#发放");
                        cmcFeignApi.addCouponReceive(shopId, GlobalConstant.CouponType.FIRST_COUPON, 1);
                    }
                    //双十一活动，发放优惠券
                    addCoupon(mapResult,shopId);
                }
                System.out.println("支付返回："+result);
                return WrapMapper.ok(result);
            } else {
                return WrapMapper.error("生成订单失败");
            }
        }

        return WrapMapper.ok(mapResult);
    }

    // 获取用户订单数（不包括已取消及无效作废的）
    @GetMapping("/getUserOrderCount/{userId}")
    public Wrapper getUserOrderCount(@PathVariable Long userId) {
        int count = 0;
        Example example = new Example(OdsOrder.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userId", userId);
        criteria.andNotEqualTo("orderStatus", 3); // 已取消
        criteria.andNotEqualTo("orderStatus", 6); // 已作废
        count = odsOrderService.selectCountByExample(example);
        return WrapMapper.ok(count);
    }

    @PostMapping("/getOrderInformation")
    public Wrapper<PageInfo<OrderShopDto>> getOrderInformation(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                               @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size,
                                                               @ApiParam(name = "orderShopDto", value = "记录orderShopDto") @RequestBody(required = false) OrderShopDto orderShopDto) {
        PageHelper.startPage(page, size);
        if (orderShopDto.getBeginTime() != null && orderShopDto.getEndTime() != null){
            orderShopDto.setBeginTime(DateUtil.getStringDate(new Date(Long.parseLong(orderShopDto.getBeginTime()))));
            orderShopDto.setEndTime(DateUtil.getStringDate(new Date(Long.parseLong(orderShopDto.getEndTime()))));
        }
        System.out.println(orderShopDto);
        List<OrderShopDto> order = odsOrderService.getOrderInformation(orderShopDto);
        PageInfo pageInfo = new PageInfo(order);
        return WrapMapper.ok(pageInfo);
    }

    //活跃度降低的店铺:已发货已确认
    @RequestMapping("/findDescShop")
    public Wrapper<PageInfo<OrderShopDto>> getDescShop(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                       @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size,
                                                       @ApiParam(name = "beginTime", value = "记录beginTime")  @RequestParam(value = "date") @DateTimeFormat(pattern="yyyy-MM-dd") Date beginTime

    ){

        PageInfo<OrderShopDto> order = odsOrderService.findDescShop(beginTime, page, size);

        return  WrapMapper.ok(order);
    }

    //每个店铺最后一次下单时间和下单金额
    @RequestMapping("/lastOrder")
    public Wrapper<PageInfo<OdsOrderApiDto>> getLastOrder(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                        @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size){

        PageInfo<OdsOrderApiDto> order = odsOrderService.getLastOrder(page,size);

        int size1 = order.getSize();

        return WrapMapper.ok(order);
    }
    //从未下过订单的店铺
    @RequestMapping("/findNoOrderShop")
    public Wrapper<PageInfo<ShopInfoDto>> findNoOrderShop(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                        @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size){

        PageInfo<ShopInfoDto> order = odsOrderService.findNoOrderShop(page,size);

        return WrapMapper.ok(order);
    }

    private void addCoupon(Map<String, String> mapResult,Long shopId){
        Integer totalPay = 0;
        if (mapResult.get("totalpay") != null){
            totalPay = Integer.valueOf(mapResult.get("totalpay"));
        }
        if (totalPay >= 50000){
            cmcFeignApi.addCouponActive(shopId,99, 1,60L);
        }else if (totalPay >= 30000){
            cmcFeignApi.addCouponActive(shopId,99, 1,59L);
        }
    }
    //统计店铺的下单金额countByShopIds
    @RequestMapping("/countByShopIds")
    public List<OdsOrderApiDto> countByShopIds(@ApiParam(name = "page", value = "分页值", defaultValue = "0") @RequestParam(defaultValue = "0") Integer page,
                                                          @ApiParam(name = "size", value = "每分页返回的记录数", defaultValue = "0") @RequestParam(defaultValue = "0") Integer size){

        List<Long> shopIdList = new ArrayList<>();

        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        String beginTime = formatter.format(com.yuke.cloud.common.util.DateUtil.monthTimeBegin());

        String endTime = formatter.format(com.yuke.cloud.common.util.DateUtil.monthTimeEnd());

        List<OdsOrderApiDto> list = odsOrderService.countByShopIds(shopIdList,beginTime,endTime);

        return list;
    }





}
